package emulator;

import java.io.FileInputStream;

import emulator.GUI.VicUI;
import emulator.assembler.Assembler;
import emulator.cbm.basic.BasicHelper;
import emulator.hardware.bus.VicBus;
import emulator.hardware.bus.VideoBus;
import emulator.hardware.clock.Clock;
import emulator.hardware.clock.ClockImpl2;
import emulator.hardware.custom.Fe3Memory;
import emulator.hardware.io.Via6522;
import emulator.hardware.io.peripherals.Joystick;
import emulator.hardware.io.peripherals.KeyboardMatrix;
import emulator.hardware.io.peripherals.SerialPort;
import emulator.hardware.io.peripherals.iec.IecSim;
import emulator.hardware.nmos6502.Cpu6502;
import emulator.hardware.video.Vic6561;
import emulator.shell.DebugShell;
import emulator.shell.GUI.ShellUI;

public class VicMain {

	/**
	 * @param args
	 * @throws EmulatorException 
	 */
	public static void main(String[] args) throws Exception {
		Fe3Memory memory = new Fe3Memory();
		memory.loadFromStream(new FileInputStream("data\\characters.901460-03.bin"), 0x8000, 0x1000);
		memory.loadFromStream(new FileInputStream("data\\pal.bin"), 0xC000, 0x4000);
		
		BasicHelper.setMemoryBlock(memory);
		
		Assembler assembler = new Assembler();
		assembler.loadSymbols(new FileInputStream("data\\vicrom.sym"));
		
		Cpu6502 cpu = new Cpu6502();
		Vic6561 vic = new Vic6561();
		Via6522 via1 = new Via6522();
		Via6522 via2 = new Via6522();
		
		VicBus bus = new VicBus(memory.getMemoryBus(), vic, via1, via2);
		bus.setIO3(memory.getIoBus());
		
		Clock clock = new ClockImpl2();
		
		cpu.attach(bus, clock);
		cpu.start();

		vic.attach(new VideoBus(memory), clock);
		vic.start();
		
		via1.attach(clock, cpu.getNmiIn());
		via1.start();
		via2.attach(clock, cpu.getIrqIn());
		via2.start();

		SerialPort iec_port = new SerialPort();
		iec_port.attachToVia(via2, via1);
		
		IecSim iec_sim = new IecSim();
		iec_sim.attach(clock, iec_port);
		iec_sim.start();
		
		ShellUI ui = new ShellUI(cpu, memory, bus);
		ui.setAssembler(assembler);
		ui.setIecSim(iec_sim);
		DebugShell shell = new DebugShell(ui.createIn(), ui.createOut(), ui.createErr());
		shell.init(cpu, bus);
		shell.setMemory(memory.getMemoryBus());
		shell.setMemoryBlock(memory);
		shell.setAssembler(assembler);
		if (args.length > 0)
			shell.setStartScript(args[0]);
		shell.start();

		KeyboardMatrix matrix = new KeyboardMatrix();
		matrix.attachToVia(via2, via1);
		VicUI.setMatrix(matrix);
		VicUI.setKeyboardMapName("data\\keymap.ini");

		Joystick joystick = new Joystick();
		joystick.attachToVia(via2, via1);
		VicUI.setJoystick(joystick);
		
/*		VicTape tape = new VicTape();
		tape.attachToVia(via2, via1);
		VicUI.setTape(tape);*/
		
		VicUI.setClock(clock);
		VicUI.setCpu(cpu);
		VicUI.run();
	}
}
